/*
 * Time : 2022/12/3 17:59
 * Auth : weixinlong
 * Email : weixinlong@buaa.edu.cn
 * File : media.go
 */

package handler

import (
	"context"
	"errors"
	"fmt"
	"hertz/demo/biz/model"
	"hertz/demo/biz/mw"
	"hertz/demo/biz/util"
	"net/http"
	"strconv"

	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/common/hlog"
	"gorm.io/gorm"
)

func AddMedia(ctx context.Context, c *app.RequestContext) {
	type Req struct {
		Path string `json:"path"`
	}
	// BindAndValidate
	var req Req
	err := c.BindAndValidate(&req)
	if err != nil {
		util.ResponseFail(c, "bind fail")
		return
	}

	record := model.Media{Path: req.Path}
	mw.GetDB(c).Create(&record)

	util.ResponseSuccess(c, "null")
}

func GetAllMedia(ctx context.Context, c *app.RequestContext) {
	var records []model.Media

	_ = mw.GetDB(c).Find(&records)
	util.ResponseSuccess(c, records)
}

func ListAllMedia(ctx context.Context, c *app.RequestContext) {
	db := mw.GetDB(c)
	stage := c.Query("stage")
	if stage != "" && !model.IsValidMediaStage(stage) {
		util.BadRequest(c, fmt.Errorf("invalid stage: %s", stage))
		return
	}
	ret, err := model.ListAllMedia(db, stage)
	if err != nil {
		hlog.CtxErrorf(ctx, "ListAllMedia db error: %w", err)
		util.ErrMessage(c, http.StatusInternalServerError, "db error")
		return
	}
	c.JSON(http.StatusOK, ret)
}

func FindMediaByID(ctx context.Context, c *app.RequestContext) {
	id, err := util.GetParamUint(c, "id")
	if err != nil {
		util.BadRequest(c, err)
		return
	}

	db := mw.GetDB(c)
	ret, err := model.FindMediaByID(db, uint(id))
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			c.NotFound()
		} else {
			hlog.CtxErrorf(ctx, "ListAllMedia db error: %w", err)
			util.ErrMessage(c, http.StatusInternalServerError, "db error")
		}
		return
	}

	c.JSON(http.StatusOK, ret)
}

func ListMediaLabel(ctx context.Context, c *app.RequestContext) {
	id, err := util.GetParamUint(c, "id")
	if err != nil {
		util.BadRequest(c, err)
		return
	}

	status := c.Query("status")
	if status != "" && !model.IsValidLabelStatus(status) {
		util.BadRequest(c, fmt.Errorf("invalid status filter"))
		return
	}

	var author *uint64 = nil
	rawAuthor := c.Query("author")
	if rawAuthor != "" {
		ret, err := strconv.ParseUint(rawAuthor, 10, 64)
		if err != nil {
			util.BadRequest(c, fmt.Errorf("invalid author id: %w", err))
			return
		}
		author = &ret
	}

	db := mw.GetDB(c)
	ret, err := model.ListMediaLabel(db, uint(id), status, author)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			c.NotFound()
		} else {
			hlog.CtxErrorf(ctx, "ListMediaLabel db error: %w", err)
			util.ErrMessage(c, http.StatusInternalServerError, "db error")
		}
		return
	}

	c.JSON(http.StatusOK, ret)
}
